package com.autohammal.ui.frame;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;

import swing2swt.layout.BorderLayout;

import com.autohammal.exception.AutoHammalRuntimeException;
import com.autohammal.exception.NotSupportPropertyEditorException;
import com.autohammal.ui.frame.items.ItemDescriptor;
import com.autohammal.ui.frame.items.PropertyEditor;

public class ItemsConfigComposite extends Composite {

	/**
	 * Create the composite.
	 * 
	 * @param parent
	 * @param style
	 */
	public ItemsConfigComposite(Composite parent, int style) {
		super(parent, SWT.NONE);
	}

	private Map<ItemDescriptor, Composite> controlDesMap = new ConcurrentHashMap<ItemDescriptor, Composite>();

	public ItemsConfigComposite(ItemDescriptor[] itemsDes, Composite parent,
			int style) {
		super(parent, style);
		initialize(itemsDes);
	}

	private void initialize(ItemDescriptor[] itemsDes) {
		setLayout(new GridLayout(1, false));
		if (itemsDes == null || itemsDes.length == 0) {
			// to do no item configuration
			return;
		}
		for (ItemDescriptor itemDes : itemsDes) {
			regiestMap(itemDes);
		}
	}

	private void regiestMap(ItemDescriptor itemDes) {
		Composite composite = makeComposite(itemDes);
		GridData gd_composite = new GridData(SWT.FILL, SWT.TOP, true, true, 1, 1);
		gd_composite.widthHint=240;
		gd_composite.heightHint=17;
		composite.setLayoutData(gd_composite);
		controlDesMap.put(itemDes, composite);
		
	}

	private Composite makeComposite(ItemDescriptor itemDes) {
		Composite group = new Composite(this, SWT.None);
		group.setLayout(new BorderLayout(0, 0));
		String labelText = itemDes.getDisplayName() == null ? itemDes.getName()
				: itemDes.getDisplayName();
		CLabel clblel = new CLabel(group, SWT.NONE);
		clblel.setLayoutData(BorderLayout.WEST);
		clblel.setText(labelText);
		clblel.setToolTipText(itemDes.getShortDescription());
		Object editor=makeEditor(group, itemDes);
		if(editor instanceof org.eclipse.swt.widgets.Control){
			((org.eclipse.swt.widgets.Control)editor).setLayoutData(BorderLayout.CENTER);
		}else{
			//to do other category
		}
		return group;
	}

	private Object makeEditor(Composite parent, ItemDescriptor itemDes) {
		Class<?> clz = itemDes.getPropertyEditorClass();
		if (clz == null) {
			clz = StyledText.class;
		}
		if (eq(clz, "org.eclipse.swt.widgets.Text")) {
			return new Text(parent, SWT.BORDER);
		} else if (eq(clz, "org.eclipse.swt.custom.StyledText")) {
			return new StyledText(parent, SWT.BORDER|SWT.SINGLE);
		} else if (eq(clz, PropertyEditor.class)) {
			try {
				PropertyEditor editor = (PropertyEditor) clz.newInstance();
				editor.setParent(parent);
				return editor;
			} catch (Exception e) {
				throw new AutoHammalRuntimeException(e);
			}
		} else {
			throw new NotSupportPropertyEditorException(clz + " not support.");
		}
	}

	private boolean eq(Class<?> clz, String className) {
		if (clz != null) {
			// class java.xx.xx
			return clz.toString().substring(6).equalsIgnoreCase(className);
		}
		return false;
	}

	private boolean eq(Class<?> clz, Class<?> interfaceClz) {
		if (clz != null) {
			if (clz.equals(interfaceClz)) {
				return true;
			} else {
				Class<?>[] clzzs = clz.getInterfaces();
				for (Class<?> clzz : clzzs) {
					if (clzz.equals(interfaceClz)) {
						return true;
					}
				}
			}
		}
		return false;
	}

	@Override
	protected void checkSubclass() {
	}

}
